﻿using System;
using System.Collections;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Xml.Linq;
using WeChat.Common;
using System.Web.UI.MobileControls;
using System.Collections.Generic;
using System.Web.Security;

namespace WeChat
{
    /// <summary>
    /// 验证服务器url地址和token值，成为开发者
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    public class UrlVerify : IHttpHandler
    {

        public void ProcessRequest(HttpContext context)
        {
            //微信服务器将发送GET请求到填写的服务器地址URL上,用以下方法获取数据
            string echoString = context.Request.QueryString["echoStr"];
            string signature = context.Request.QueryString["signature"];
            string timestamp = context.Request.QueryString["timestamp"];
            string nonce = context.Request.QueryString["nonce"];

            String TOKEN = "weixin";//token值要和微信服务器填写的一致
            if (string.IsNullOrEmpty(TOKEN))
            {
                throw new Exception("TOKEN is not defined!");
            }
            String token = TOKEN;
            
            /*
             * 开发者通过检验signature对请求进行校验：
             * 1. 将token、timestamp、nonce三个参数进行字典序排序
             * 2. 将三个参数字符串拼接成一个字符串进行sha1加密
             * 3. 开发者获得加密后的字符串可与signature对比，标识该请求来源于微信
             */

            /*
             * string[] arrTmp = { a, b, c };
             * Array.Sort(arrTmp);//字典排序
             * string signature = string.Join("", arrTmp);
             */
            String verify = "";
            SortedDictionary<String, String> a = new SortedDictionary<String, String>();
            a.Add(token, token);
            a.Add(timestamp, timestamp);
            a.Add(nonce, nonce);
            foreach (KeyValuePair<string, string> k in a)//按key值 字典序排序
            {
                string m = k.Value;
                verify = verify + m;
            }
            ApplicationLog.Write("接收微信接入验证参数：token = " + token + ";timestamp = " + timestamp + ";nonce = " + nonce + ";signature = " + signature);
            ApplicationLog.Write("（sha1加密前）verify:" + verify);

            //sha1加密
#pragma warning disable CS0618 // “FormsAuthentication.HashPasswordForStoringInConfigFile(string, string)”已过时:“The recommended alternative is to use the Membership APIs, such as Membership.CreateUser. For more information, see http://go.microsoft.com/fwlink/?LinkId=252463.”
            verify = FormsAuthentication.HashPasswordForStoringInConfigFile(verify,"SHA1").ToLower();
#pragma warning restore CS0618 // “FormsAuthentication.HashPasswordForStoringInConfigFile(string, string)”已过时:“The recommended alternative is to use the Membership APIs, such as Membership.CreateUser. For more information, see http://go.microsoft.com/fwlink/?LinkId=252463.”

            //若确认此次GET请求来自微信服务器，请原样返回echostr参数内容，则接入生效，成为开发者成功，否则接入失败。
            if (signature.Equals(verify))
            {
                context.Response.Write(echoString);
                context.Response.End();
                ApplicationLog.Write("验证成功！（sha1加密后）verify:" + verify);
            }
            else
            {
                ApplicationLog.Write("验证失败！（sha1加密后）verify:" + verify);
            }
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}
